/*
 * Copyright 2013 JROSE
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.jrose.core.jdbc.persistence.executor;

import org.apache.commons.lang3.StringUtils;
import org.jrose.core.jdbc.DatabaseConnection;
import org.jrose.core.jdbc.datasource.RoutingPolicy;
import org.jrose.core.jdbc.datasource.RoutingPolicyCallback;
import org.jrose.core.jdbc.datasource.RoutingPolicyTemplate;
import org.jrose.core.jdbc.entity.EntityDefinition;
import org.jrose.core.jdbc.persistence.annotation.RequireQuery;
import org.jrose.core.jdbc.persistence.annotation.SqlTemplate;
import org.jrose.core.jdbc.persistence.query.Sql;
import org.jrose.core.util.ExtendedMap;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

import java.io.Serializable;

@SqlTemplate("DELETE FROM ${TABLE} ${QUERY}")
@RequireQuery(allowEmptyCriteria = false)
public class DeleteSqlExecutor<E extends Serializable> extends AbstractSqlExecutor<E> {
    public DeleteSqlExecutor(DatabaseConnection databaseConnection, EntityDefinition<E> entityDefinition) {
        super(databaseConnection, entityDefinition);
    }

    @Override
    protected Sql generateNamedParameterSQL(String templateSQL) {
        String candidateSQL = templateSQL;
        Sql sql = this.query.generateQuerySQL(entityDefinition);
        candidateSQL = StringUtils.replace(candidateSQL, "${QUERY}", sql.getSqls().get(0));
        sql.setCandidateSQL(candidateSQL);
        return sql;
    }

    @Override
    protected ExtendedMap doExecute(final Sql sql) {
        return RoutingPolicyTemplate.execute(RoutingPolicy.usingMaster, new RoutingPolicyCallback<ExtendedMap>() {
            @Override
            public ExtendedMap doInRoutingPolicy() {
                NamedParameterJdbcTemplate namedParameterJdbcTemplate = databaseConnection.getNamedParameterJdbcTemplate();
                MapSqlParameterSource parameterSource = new MapSqlParameterSource();
                parameterSource.addValues(sql.getNamedParameters());
                int rows = namedParameterJdbcTemplate.update(sql.getCandidateSQL(), parameterSource);
                return ExtendedMap.set("ROWS", rows);
            }
        });
    }
}
